﻿
using System;
using System.Text;
using System.Threading;
using System.Windows.Threading;
using RiskMan.Config;
using Trans2QuikAPI_0;
using Timer = System.Threading.Timer;

using System.Collections.Generic;
using System.Windows;
using RiskMan.Models;
using TheDoubleStop.Models;
using RiskMan.Providers.QuikIO;
using System.Reflection;


namespace RiskMan.Providers.QuikIO
{
    

    public class QuikTerminal_0 : AbstractEventHandlers
    {
        private StringBuilder msg = new StringBuilder(256);
        private String acc;
        public bool IsConnected = false;
        private int error = 0;
       
        public String Key = "";
        public String Path = "";


        public QuikTerminal_0(String key, RiskMan.DataClass.Data data)
        {
            this.Key = key;
            IsConnected = false;
            this.data = data;
        }

        public void Connect ( String path )
        {
            this.Path = path;
            Random r = new Random( );
            len = r.Next( 10000, 999999 );
            if ( Trans2QuikAPI_0.Trans2Quik.SET_CONNECTION_STATUS_CALLBACK( StatusCallback, out error, msg, msg.Capacity ) != Trans2QuikAPI_0.Trans2Quik.Result.SUCCESS
               || Trans2QuikAPI_0.Trans2Quik.SET_TRANSACTIONS_REPLY_CALLBACK( TransactionReplyCallback, out error, msg, msg.Capacity ) != Trans2QuikAPI_0.Trans2Quik.Result.SUCCESS
               )
            {
                IsConnected = false;
                return;
            }
            bool e = false;
            Trans2QuikAPI_0.Trans2Quik.Result result = 0;
            try
            {
                result = Trans2QuikAPI_0.Trans2Quik.CONNECT( path, out error, msg, msg.Capacity );
                OnChangedStatus( msg.ToString(), Key, true, result );
            }
            catch ( Exception )
            {
                e = true;
            }

            if ( e == true )
            {
                return;
            }

            if ( result != Trans2QuikAPI_0.Trans2Quik.Result.SUCCESS && result != Trans2QuikAPI_0.Trans2Quik.Result.ALREADY_CONNECTED_TO_QUIK )
            {
                IsConnected = false;

                return;
            }
            IsConnected = true;
        }

        void StatusCallback(Trans2QuikAPI_0.Trans2Quik.Result evnt, int err, string m)
        {
            try
            {
                OnChangedStatus( m, Key, true, evnt );
                switch (evnt)
                {
                    case Trans2QuikAPI_0.Trans2Quik.Result.QUIK_DISCONNECTED:
                        IsConnected = false;
                        break;
                    case Trans2QuikAPI_0.Trans2Quik.Result.DLL_DISCONNECTED:
                        IsConnected = false;
                        break;
                    case Trans2QuikAPI_0.Trans2Quik.Result.QUIK_CONNECTED:
                        {
                            IsConnected = true;
                        } break;
                }
                
            }
            catch (Exception)
            { }
        }

        void TransactionReplyCallback(
                    Trans2QuikAPI_0.Trans2Quik.Result r,
                    int err,
                    int rc,
                    int tid,
                    double order_id,
                    string msg)
        {
            if (order_id <= 0 && tid != 500)
            {
                List<StopOrderModel> result = new List<StopOrderModel>();
                for (int i = 0; i < data.StopLossOrderList.Count; i++)
                    if (data.StopLossOrderList[i].TID != tid)
                        result.Add(data.StopLossOrderList[i]);
                data.StopLossOrderList = result;

            }

            foreach (var item in data.StopLossOrderList)
	        {
                if (item.TID == tid)
                    acc = item.ClientCode.ToString();
	        }


            OnTransStatus( r, tid, order_id, msg );
            OnTransStatusAcc(r, tid, order_id, msg, acc);

            Cfg.SetLog( msg, GetType( ), MethodBase.GetCurrentMethod( ) );
            switch (r)
            {
                case Trans2QuikAPI_0.Trans2Quik.Result.SUCCESS:
                    IsConnected = true;
                    break;
                case Trans2QuikAPI_0.Trans2Quik.Result.DLL_NOT_CONNECTED:
                    IsConnected = false;
                    break;
                case Trans2QuikAPI_0.Trans2Quik.Result.QUIK_NOT_CONNECTED:
                    IsConnected = false;
                    break;
                case Trans2QuikAPI_0.Trans2Quik.Result.FAILED:
                    break;
            }
        }

        public void Disconnect()
        {
            try
            {
                Trans2QuikAPI_0.Trans2Quik.DISCONNECT(out error, msg, msg.Capacity);
                IsConnected = false;
            }
            catch (Exception)
            {
            }
        }

        private int len = 0;
        
        private RiskMan.DataClass.Data data;

        public int SendStopOrder(char operation, double stopprice, double price, int lot, string secCode, string classCode, string account, string clientcode)
        {
            if (IsConnected)
            {
                len++;

                Trans2QuikAPI_0.Trans2Quik.Result r = Trans2QuikAPI_0.Trans2Quik.SEND_ASYNC_TRANSACTION(
                  String.Format("ACTION={0}; ACCOUNT={1}; TRANS_ID={2}; CLASSCODE={3}; SECCODE={4}; OPERATION={5}; QUANTITY={6}; CLIENT_CODE={7}; STOPPRICE={8}; PRICE={9};", 
                  "NEW_STOP_ORDER",
                  account,
                  len,
                  classCode,
                  secCode,
                  operation,
                  lot,
                  clientcode,
                  stopprice,
                  price
                  ),
                  out error, msg, msg.Capacity);

                if (r == Trans2QuikAPI_0.Trans2Quik.Result.SUCCESS)
                {
                    return len;
                }
            }
            return len;
        }

        public int SendTakeProfit(char op, double stopprice, string clientcode, string seccode, string classcode, string account, int lot, double offset, double spread, string units)
        {
            if (IsConnected)
            {
                len++;
                Trans2QuikAPI_0.Trans2Quik.Result r = Trans2QuikAPI_0.Trans2Quik.SEND_ASYNC_TRANSACTION(
                   String.Format("ACTION=NEW_STOP_ORDER;" +
                                 "TRANS_ID               ={0};" +
                                 "STOP_ORDER_KIND=TAKE_PROFIT_STOP_ORDER;" +
                                 "STOPPRICE              ={1};" +
                                 "CLIENT_CODE            ={2};" +
                                 "OPERATION              ={3};" +
                                 "SECCODE                ={4};" +
                                 "CLASSCODE              ={5};" +
                                 "ACCOUNT                ={6};" +
                                 "QUANTITY               ={7};" +
                             //  "EXPIRY_DATE            =GTS;"+
                                 "OFFSET                 ={8};" +
                                 "OFFSET_UNITS={9};" +
                                 "SPREAD={10};" +
                                 "SPREAD_UNITS={11};",
                         len, stopprice, clientcode, op, seccode, classcode, account, lot, offset, units, spread, units
                   ),
                   out error, msg, msg.Capacity);

                if (r == Trans2QuikAPI_0.Trans2Quik.Result.SUCCESS)
                {
                    return len;
                }
            }
            return len;
        }

        public int SendStopAndTake(char op, String classcode, String seccode, String account, String clientcode, int lot, double price, double stopprice, double offset, string units, double spread, string byMarket, double stopprice2 )
        {
            if (IsConnected)
            {
                len++;
                Trans2QuikAPI_0.Trans2Quik.Result r = Trans2QuikAPI_0.Trans2Quik.SEND_ASYNC_TRANSACTION(
                   String.Format("ACTION=NEW_STOP_ORDER;"+
                                 "TRANS_ID          ={0};"+
                                 "CLASSCODE         ={1};"+
                                 "SECCODE           ={2};"+
                                 "ACCOUNT           ={3};"+
                                 "CLIENT_CODE       ={4};"+
                                 "OPERATION         ={5};"+
                                 "QUANTITY          ={6};"+
                                 "PRICE             ={7};"+
                                 "STOPPRICE         ={8};"+
                                 "STOP_ORDER_KIND=TAKE_PROFIT_AND_STOP_LIMIT_ORDER;"+
                                 "OFFSET            ={9};"+
                                 "OFFSET_UNITS      ={10};"+
                                 "SPREAD            ={11};"+
                                 "SPREAD_UNITS      ={12};"+
                                 "MARKET_TAKE_PROFIT={13};"+
                                 "STOPPRICE2        ={14};"+
                                 "MARKET_STOP_LIMIT ={15};",
                   len, classcode, seccode, account, clientcode, op, lot, price, stopprice, offset, units,
                   spread, units, byMarket, stopprice2, byMarket),
                   out error, msg, msg.Capacity);

                if (r == Trans2QuikAPI_0.Trans2Quik.Result.SUCCESS)
                {
                    return len;
                }
            }
            return len;
        }

        public int SendOrder(char operation, double price, int lot, string secCode, string classCode, string account, string clientcode)
        {
            if (IsConnected)
            {
                len++;

                Trans2QuikAPI_0.Trans2Quik.Result r = Trans2QuikAPI_0.Trans2Quik.SEND_ASYNC_TRANSACTION(
                  String.Format("ACCOUNT={0}; CLIENT_CODE={1}; TYPE=L; TRANS_ID={2}; CLASSCODE={3}; SECCODE={4}; ACTION=NEW_ORDER; OPERATION={5}; PRICE={6}; QUANTITY={7};",
                    account,
                    clientcode,
                    len,
                    classCode,
                    secCode,
                    operation,
                    price,
                    lot
                  ),
                  out error, msg, msg.Capacity);

                if (r == Trans2QuikAPI_0.Trans2Quik.Result.SUCCESS)
                    return len;
            }
            return len;
        }

        public string CancelStopOrder(long number, string secCode, string classCode, string account, string clientcode)
        {
            if (IsConnected)
            {
                string trans = "ACTION=KILL_STOP_ORDER; CLASSCODE={0}; SECCODE={1}; STOP_ORDER_KEY={2}; TRANS_ID=500; ACCOUNT={3}; CLIENT_CODE={4};";
                Trans2QuikAPI_0.Trans2Quik.Result r = Trans2QuikAPI_0.Trans2Quik.SEND_ASYNC_TRANSACTION
                    (
                        String.Format(trans, 
                        classCode, 
                        secCode, 
                        number, 
                        account, 
                        clientcode
                    ),
                  out error, msg, msg.Capacity);

                if (r == Trans2QuikAPI_0.Trans2Quik.Result.SUCCESS)
                {
                    return null;
                }
                return msg.Length == 0 ? r + ", " + error : msg.ToString();
            }
            return "No Connection";
        }

        public string CancelOrder(long number, string secCode, string classCode)
        {
            if (IsConnected)
            {
                string trans = "CLASSCODE={0}; SECCODE={1}; TRANS_ID=5; ACTION=KILL_ORDER; ORDER_KEY={2};";
                Trans2QuikAPI_0.Trans2Quik.Result r = Trans2QuikAPI_0.Trans2Quik.SEND_ASYNC_TRANSACTION(
                    String.Format( trans, classCode, secCode, number ),
                    out error, msg, msg.Capacity);

                if (r == Trans2QuikAPI_0.Trans2Quik.Result.SUCCESS)
                {
                    return null;
                }
                return msg.Length == 0 ? r + ", " + error : msg.ToString();
            }
            return "No Connection";
        }

        public void Market ( char type, double price, string classcode, string seccode, int lot, string account, string clientcode )
        {
            if ( IsConnected )
            {

                String trans = "TRANS_ID=90009; ACCOUNT=" + account +
                  "; CLIENT_CODE=" + clientcode +
                  "; SECCODE=" + seccode +
                  "; CLASSCODE=" + classcode +
                  "; ACTION=NEW_ORDER; OPERATION=" + type +
                  "; PRICE=" + price +
                  "; QUANTITY=" + lot +
                  ";TYPE=L";

                Trans2Quik.Result r = Trans2Quik.SEND_ASYNC_TRANSACTION(
                trans,
                 out error, msg, msg.Capacity );
            }
        }

        public int MMMarketID( char type, string classcode, string seccode, int lot, string account, string clientcode )
        {
            if ( IsConnected )
            {
                len++;

                String trans = "TRANS_ID=" + len + "; ACCOUNT=" + account +
                  "; CLIENT_CODE=" + clientcode +
                  "; SECCODE=" + seccode +
                  "; CLASSCODE=" + classcode +
                  "; ACTION=NEW_ORDER; OPERATION=" + type +
                  "; PRICE=" + 0 +
                  "; QUANTITY=" + lot +
                  ";TYPE=M";

                Trans2Quik.Result r = Trans2Quik.SEND_ASYNC_TRANSACTION(
                trans,
                 out error, msg, msg.Capacity );

                if (r == Trans2QuikAPI_0.Trans2Quik.Result.SUCCESS)
                    return len;
            }
            return len;
        }

        public void MMMarket(char type, string classcode, string seccode, int lot, string account, string clientcode)
        {
            if (IsConnected)
            {
                len++;

                String trans = "TRANS_ID=90009; ACCOUNT=" + account +
                  "; CLIENT_CODE=" + clientcode +
                  "; SECCODE=" + seccode +
                  "; CLASSCODE=" + classcode +
                  "; ACTION=NEW_ORDER; OPERATION=" + type +
                  "; PRICE=" + 0 +
                  "; QUANTITY=" + lot +
                  ";TYPE=M";

                Trans2Quik.Result r = Trans2Quik.SEND_ASYNC_TRANSACTION(
                trans,
                 out error, msg, msg.Capacity);
            }
        }

        public int SendLinkedOrder(string account, string classcode, string seccode, char op, int lot, string clientcode, double stop_price, double price, double linked_price)
        {
            if (IsConnected)
            {
                len++;

                Trans2QuikAPI_0.Trans2Quik.Result r = Trans2QuikAPI_0.Trans2Quik.SEND_ASYNC_TRANSACTION(
                  String.Format("ACTION=NEW_STOP_ORDER; STOP_ORDER_KIND=WITH_LINKED_LIMIT_ORDER; ACCOUNT= {0}; TRANS_ID={1}; CLASSCODE={2}; SECCODE={3}; OPERATION={4}; QUANTITY={5}; CLIENT_CODE={6}; STOPPRICE={7}; PRICE={8}; LINKED_ORDER_PRICE={9}; KILL_IF_LINKED_ORDER_PARTLY_FILLED=NO;",               
                  account,
                  len,
                  classcode,
                  seccode,
                  op,
                  lot,
                  clientcode,
                  stop_price,
                  price,
                  linked_price 
                  ),
                  out error, msg, msg.Capacity);

                if (r == Trans2QuikAPI_0.Trans2Quik.Result.SUCCESS)
                {
                    return len;
                }
            }
            return len;
        }

        internal int SendMoveOrder(string classcode, string seccode, long number, double price, int lot)
        {
            if (IsConnected)
            {
                len++;

                Trans2QuikAPI_0.Trans2Quik.Result r = Trans2QuikAPI_0.Trans2Quik.SEND_ASYNC_TRANSACTION(
                                "ACTION=MOVE_ORDERS;"
                              + "TRANS_ID=" + len + ";"
                              + "CLASSCODE=" + classcode + "; "
                              + "SECCODE=" + seccode + "; "
                              + "MODE=1; "
                              + "FIRST_ORDER_NUMBER=" + number + "; "
                              + "FIRST_ORDER_NEW_PRICE=" + price + "; "
                              + "FIRST_ORDER_NEW_QUANTITY=" + lot + ";",
                  out error, msg, msg.Capacity);
                if (r == Trans2QuikAPI_0.Trans2Quik.Result.SUCCESS)
                    return len;
            }
            return len;
        }

        public int SendSOWithOtherEmitent( string classcode, string seccode, 
                                             string stoppriceclasscode, string stoppriceseccode,
                                             string account, string clientcode,
                                             double stopprice, double price, double lot)
        {
            if ( IsConnected )
            {
                len++;
                Trans2Quik.Result r = Trans2Quik.SEND_ASYNC_TRANSACTION(
                                "ACTION=NEW_STOP_ORDER;" +
                                "STOP_ORDER_KIND=CONDITION_PRICE_BY_OTHER_SEC;" +
                                "ACCOUNT= " + account + ";" + 
                                "QUANTITY=" + lot + ";" +
                                "TRANS_ID=" + len + ";" + 
                                "CLASSCODE=" + classcode + ";" + 
                                "SECCODE=" + seccode + ";" + 
                                "STOPPRICE_CLASSCODE=" + stoppriceclasscode + ";" + 
                                "STOPPRICE_SECCODE=" + stoppriceseccode + ";" +
                                "STOPPRICE_CONDITION=<=;" +
                                "OPERATION=B;" + 
                                "CLIENT_CODE=" + clientcode + ";" + 
                                "STOPPRICE=" + stopprice + ";"+
                                "PRICE=" + price + ";",
                out error, msg, msg.Capacity );

             

                if ( r == Trans2Quik.Result.SUCCESS )
                    return len;
            }
            return len;
        }
    }
}
